import java.awt.Color;
import se.lth.cs.ptdc.images.ImageFilter;

/** IdentityFilter beskriver en identitetstransformation */
public class ContrastFilter extends ImageFilter {
	/** skapa ett filterobjekt med namnet name */
	Color[] m_grayLevels = new Color[256];
	public ContrastFilter(String name) {
		super(name);
		
		// Skapa alla grayLevel färgerna
		for(int i = 0; i < 256; i++){
			m_grayLevels[i] = new Color(i,i,i);
		}
	}
	
	/** filtrera bilden i matrisen inPixels och returnera resultatet i
		en ny matris. Utnyttja eventuellt värdet av parameter */
	public Color[][] apply(Color[][] inPixels, double paramValue) {
		//Gör om pareamValue till mer användbart värde
		double cutOff = paramValue/100;
		int height = inPixels.length;
		int width = inPixels[0].length;
		int pixels = height*width;
		
		int[] histogram = new int[256];
		
		short[][] intensity = computeIntensity(inPixels);
		
		//Räkna ut hur många pixlar har vajre intesitet
		for (int i = 0; i < height; ++i) {
            for (int j = 0; j < width; ++j) {
                histogram[intensity[i][j]] += 1;
            }
        }
		
		int lowCut = calcCuts(histogram, cutOff, pixels)[0];
		int highCut = calcCuts(histogram, cutOff,pixels)[1];
		
		Color[][] outPixels = new Color[height][width];
		for (int i = 0; i < height; ++i) {
			for (int j = 0; j < width; ++j) {
				int intens = 255 * (intensity[i][j] - lowCut) / (highCut - lowCut);
				
				if(intens >= 0 && intens <= 255) {
					outPixels[i][j] = m_grayLevels[intens];
				} else if(intens > 255) {
					outPixels[i][j] = m_grayLevels[255];
				} else if(intens < 0) {
					outPixels[i][j] = m_grayLevels[0];
				}
			}
		}
		return outPixels;
	}
	
	private int[] calcCuts(int[] histogram, double cutOff, int pixels) {
		int[] tempGram = new int[256];
		tempGram[0] = histogram[0];
		tempGram[255] = pixels;
		
		int lowCut = 0;
		int highCut = 0;
		
		for(int i = 1; i < 256; i++){
			tempGram[i] = tempGram[i-1] + histogram[i];
			if(tempGram[i] >= pixels*cutOff) {
				lowCut = i;
				break;
			}
		}
		
		for(int i = 254; i > 0; i--) {
			tempGram[i] = tempGram[i+1] - histogram[i];
			if(tempGram[i] <= pixels*(1-cutOff)) {
				highCut = i;
				break;
			}
		}
		
		int[] rv = { lowCut, highCut };
		return rv;
	}
}
